#ifndef YHAIDA_CONNECTOR_H
#define YHAIDA_CONNECTOR_H
#include "../base/Utils.h"
#include "InetAddress.h"
#include "TimeId.h"

#include "../logging/Logging.h"
#include "SocketsOps.h"

#include <functional>
#include <memory>
#include <errno.h>

namespace yhaida
{
    class Channel;
    class EventLoop;
    /*
    与TcpConnection一样
    */
    class Connector : Utils::nocapyable
    {
    public:
        typedef std::function<void(int sockfd)> NewConnectionCallFunction;

    public:
        // Connector()=default;
        Connector(EventLoop *loop, const InetAddress &serverAddr);
        ~Connector();

        void setNewConnectionCallFunction(const NewConnectionCallFunction &cb)
        {
            _newConnectionCallFunction = cb;
        }

        void start();
        void restart();
        void stop();

        const InetAddress &serverAddress() const { return _serverAddr; }

        static const int kMaxRetryDelayMs;
        static const int kInitRetryDelayMs;

    private:
        enum States
        {
            Kconnecting,
            Kconnected,
            kDisconnected,
        };

        void setState(States s) { _state = s; }

        void startInLoop();

        void connect();
        void connecting(int socket);

        void handleWrite();
        void handleError();

        void retry(int socket);

        int removeAndResetChannel();

        void resetChannel();

    private:
        EventLoop *_mainEventLoop;
        InetAddress _serverAddr;

        bool _start;
        States _state;

        std::unique_ptr<Channel> _channel;
        NewConnectionCallFunction _newConnectionCallFunction;
        
        int _retryDelayMs;
        TimerID _timeID;
    };
    // typedef std::unique_ptr<Connector> ConnectorPtr;

}

#endif